/**
 * 事件委托事件
 */

function delegate(element, eventType, selector, fn){
    element.addEventListener(eventType, e => {
        let el = e.target;
        while(!el.matches(selector)){
            if(element === el){
                el = null;
                break;
            }
            el = el.parentNode;
        }
        el && fn.call(el,e,el)
    }, true)
    return element;
}

/**
 * 实现一个DIV拖拽
 * */
// 拖拽标记位
// let dragging = false;
// // 位置记录
// let position = null;
// let element = document.getElementById("container");
// element.addEventListener("mousedown",(e) => {
//     dragging = true;
//     position = [e.clientX, e.clientY];
// })
//
// document.addEventListener("mousemove", (e) => {
//     if(dragging === false) return null;
//     const x = e.clientX;
//     const y = e.clientY;
//     const deltaX = x - position[0];
//     const deltaY = y - position[1];
//     const left = Number.parseInt(element.style.left || 0);
//     const top = Number.parseInt(element.style.top || 0);
//     element.style.left = left + deltaX + 'px';
//     element.style.top = top + deltaY + 'px';
//     position = [x, y];
// })
//
// document.addEventListener('mouseup', (e) => {
//     dragging = false;
// })

/**
 * 对象方式实现数组去重
 */
function unique(array){
    let obj = {};
    return array.filter((item,index,array) => {
        return obj.hasOwnProperty(typeof item + item) ? false: (obj[typeof item + item] = true)
    })
}

/**
 * 实现函数柯力化
 */
let currying = (fn, ...args) => {
    return fn.length > args.length ? (...arguments) => currying(fn, ...args, ...arguments) : fn(...args)
}

/**
 * 实现数组reduce
 */
Array.prototype.myReduce = function(fn,initVal){
    let result = initVal, i=0;
    if(typeof initVal === "undefined"){
        result = this[i];
        i++;
    }
    while(i< this.length){
        result = fn(result, this[i], i, this)
    }
    return result;
}

/**
 * 实现Promise.all 和 race
 */
Promise.myAll = function(arr){
    return new Promise((resolve, reject) => {
        let res = [];
        if(arr.length === 0 || arr == null) resolve(res);
        let count = 0; let len = arr.length;
        for(let i = 0; i < len; i++){
            Promise.resolve(arr[i]).then((data) => {
                res[i] = data;
                count++;
                if(count >= len){
                    resolve(res)
                }
            }).catch(err => {
                reject(err);
            })
        }
    });
}

/**
 * 手写Promise race 方法
 */
Promise.myRace = function(arr){
    return new Promise((resolve,reject) => {
        arr.forEach((item) => {
            Promise.resolve(item).then((data) => {
                resolve(data);
                return;
            }).catch(err => {
                reject(err);
                return;
            })
        })
    })
}

/**
 * 寄生组合式集成
 */
function inheritPrototype(subType,superType){
    // 创建对象， 创建父类型的一个副本
    let prototype = Object.create(superType.prototype);
    // 增强对象，弥补因从写原型链而失去默认constructor属性
    prototype.constructor = subType;
    // 指定对象，将创建的对象赋值给子类的原型
    subType.prototype = prototype;
}

class SingletonApp {
    constructor(name) {
        this.name = name;
    }
    // 静态方法中this指向的类 而不是实例
    static getInstance(name){
        if(this.instance == null){
            this.instance = new SingletonApp(name);
        }
        return this.instance;
    }
}

/**
 * Cookies
 * 容量缺陷：Cookies体积上限只有4K，只能用来存储少量信息。
 * 性能缺陷：Cookie紧跟域名，不管域名下面的某一个地址需不需要这个cookie去，请求都会带上
 * 完整的Cookie，这样随着请求数量的增多，其实会造成巨大的性能浪费，因为请求携带了很多不必要的内容
 * 安全缺陷：
 * SessionStorage：
 * 容量问题4M 无
 * 只存在客户端 无安全与性能问题
 * 接口封装
 */
